package encrypt

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"io"
	"unicode"
)

var (
	默认ASE密钥 = "hQ82M4nQbXp3nzRuQbXp3nzR"
)

type SASE加解密 struct {
	V密钥 []byte
}

// 每次加密的结果都不一样。
func F新建Ase加解密(key ...string) S加解密接口 {
	return &SASE加解密{F处理密钥格式(key...)}
}

func F处理密钥格式(key ...string) []byte {
	if (len(key)) > 0 {
		//密钥只能是16, 24或者32
		l := len(key[0])
		defal := 24
		if (l == 16 || l == 24 || l == 32) && !F是否包含中文(key[0]) {
			return []byte(key[0])
		}
		//如果少于16位
		if l < defal {
			return []byte(key[0] + 默认ASE密钥[:defal-l])
		} else {
			return []byte(key[0][:defal])
		}
	}
	return []byte(默认ASE密钥)
}

func F是否包含中文(str string) bool {
	for _, r := range str {
		if unicode.Is(unicode.Scripts["Han"], r) {
			return true
		}
	}
	return false
}

func (a *SASE加解密) F加密信息(body string) (string, error) {
	plaintext := []byte(body)
	block, err := aes.NewCipher(a.V密钥)
	if err != nil {
		return "", err
	}
	nonce := make([]byte, 12)
	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
		return "", err
	}
	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		return "", err
	}
	ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
	combined := append(nonce, ciphertext...)
	return base64.StdEncoding.EncodeToString(combined), nil
}

func (a *SASE加解密) F解密信息(body string) (string, error) {
	// Decode the base64 string
	encryptedBytes, err := base64.StdEncoding.DecodeString(body)
	if err != nil {
		return "", err
	}
	nonce := encryptedBytes[:12]
	encryptedBytes = encryptedBytes[12:]
	block, err := aes.NewCipher(a.V密钥)
	if err != nil {
		return "", err
	}
	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		return "", err
	}
	plaintext, err := aesgcm.Open(nil, nonce, encryptedBytes, nil)
	if err != nil {
		return "", err
	}
	return string(plaintext), nil
}
